<?php
/**
 * 后台customer权限下，hm的测肤建议管理
 * Author: lyun
 * Date: 2019/3/25
 * Created by Panxsoft.
 */


namespace App\Http\Controllers\Admin\Customer;

use App\Http\Controllers\ApiController;
use App\Http\Requests\Admin\Customer\Suggest\HmSkinSuggestStoreRequest;
use App\Models\Admin\CustomerAdmin;
use App\Models\Customer\CustomerRelateHmSkin;
use App\Models\Customer\HmSkinSuggest;
use App\Models\Customer\Language;
use App\Models\Store\HmSkinRecord;
use App\Services\Presenters\HmSkinData;
use App\Services\Utils\Guard;
use App\Services\Utils\Transaction;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;

class HmSkinSuggestController extends ApiController
{
    const ROUTES = [
        'index'   => 'api.admin.customer.hm.skin.suggest.index',
        'store'   => 'api.admin.customer.hm.skin.suggest.store',
        'destroy' => 'api.admin.customer.hm.skin.suggest.destroy',
    ];

    /**
     *  返回客户自定义的HM测肤建议
     * @test
     *
     * @return array|\Illuminate\Http\Response
     */
    public function index()
    {
        $login_customer_id = Guard::customer()->id;

        $suggest_customer_id = CustomerRelateHmSkin::hasHmSkinSuggest($login_customer_id);

        $hm_skin_suggests = $this->getHmSkinSuggests($suggest_customer_id);

        return $this->response(compact('hm_skin_suggests'));
    }

    /**
     * 返回HM不同检测项的分数级别
     *
     * @return array|\Illuminate\Http\Response
     */
    public function create()
    {
        // 不同检测项的分数级别
        $level_sort = HmSkinData::HM_DETECTION_LEVEL_MAP;

        $position_map = HmSkinRecord::ALL_POSITIONS;

        return $this->response(compact('level_sort', 'position_map'));
    }

    /**
     *  customer保存自定义的HM测肤建议
     * @test
     *
     * @param HmSkinSuggestStoreRequest $request
     * @return array|\Illuminate\Http\Response
     * @throws \Exception
     */
    public function store(HmSkinSuggestStoreRequest $request)
    {
        $this->isSuperAdmin();

        $customer = Guard::customer();

        $this->deleteOldHmSkinSuggest($customer->id);

        $hm_skin_suggest_data = $this->assembleHmSkinSuggest($request, $customer->id);

        $stored = Transaction::handle(function() use($hm_skin_suggest_data){
            foreach($hm_skin_suggest_data as $item)
            {
                /** @var CustomerRelateHmSkin $customer_relate_hm_skin */
                $customer_relate_hm_skin = CustomerRelateHmSkin::updateOrCreate($item['customer_relate_hm_skin']);
                $hm_skin_suggest_data_by_language = $this->assembleHmSkinSuggestByCustomerRelate($item['hm_skin_suggest'], $customer_relate_hm_skin->id);
                HmSkinSuggest::insert($hm_skin_suggest_data_by_language);
            }

            return true;
        });

        return $this->response(compact('stored'));
    }

    /**
     * customer 删除HM测肤建议
     * @test
     *
     * @param $customer_id
     * @return array|\Illuminate\Http\Response
     * @throws \Exception
     */
    public function destroy($customer_id)
    {
        $this->isSuperAdmin();

        $login_customer_id = Guard::customer()->id;
        $has_suggest = CustomerRelateHmSkin::checkHmSkinSuggest($login_customer_id);
            $this->checkIsTrue($has_suggest, trans('admin.no_customer_wax_skin_suggest'));

        $deleted = $this->deleteSuggest($login_customer_id);

        return $this->response(compact('deleted'));
    }

    /**
     * @param $customer_id
     * @throws \Exception
     */
    private function deleteOldHmSkinSuggest($customer_id)
    {
        if (CustomerRelateHmSkin::checkHmSkinSuggest($customer_id)) {
            $this->deleteSuggest($customer_id);
        }
    }

    /**
     * customer 删除wax测肤建议
     *
     * @param $customer_id
     * @return array|\Illuminate\Http\Response
     * @throws \Exception
     */
    private function deleteSuggest($customer_id)
    {
        $customer_relate_hm_skin_ids = CustomerRelateHmSkin::where('customer_id', $customer_id)
            ->where('store_id', CustomerRelateHmSkin::STORE_ID_DEFAULT)
            ->pluck('id')
            ->toArray();

        $deleted = Transaction::handle(function() use($customer_relate_hm_skin_ids){

//            CustomerRelateHmSkin::destroy($customer_relate_hm_skin_ids); // 不能删除，关联customer_relate_skin_productable表
            HmSkinSuggest::whereIn('customer_relate_hm_skin_id', $customer_relate_hm_skin_ids)->delete();

            return true;
        });

        return $deleted;
    }

    /**
     * @param $customer_id
     * @param $language_id
     * @return Collection|\Illuminate\Support\Collection
     */
    public function getHmSkinSuggests($customer_id, $language_id = null)
    {
        /** @var Collection $hm_skin_suggests */
        $hm_skin_suggests = (new HmSkinSuggest)->filterLanguageId($language_id)
            ->whereHas('customerRelateHmSkin', function ($query) use ($customer_id) {
                return $query->where('customer_id', $customer_id)
                    ->where('store_id', CustomerRelateHmSkin::STORE_ID_DEFAULT);
            })
            ->with('customerRelateHmSkin')
            ->get();

        $hm_skin_suggests = $this->transformHmSkinSuggests($hm_skin_suggests);

        return $hm_skin_suggests;
    }

    /**
     * @param Collection $hm_skin_suggests
     * @return Collection|\Illuminate\Support\Collection
     */
    private function transformHmSkinSuggests(Collection $hm_skin_suggests)
    {
        $languages = array_flip(Language::getLanguageIds());
        $hm_skin_suggests = $hm_skin_suggests->sortBy('language_id')
            ->groupBy('language_id')
            ->map(function($hm_skin_suggest, $lanugage_id) use($languages){
                return [
                    'language_id'         => $lanugage_id,
                    'language_name'       => trans('admin.'.$languages[$lanugage_id]) ?? '',
                    'suggest_by_language' => $hm_skin_suggest->sortBy('customerRelateHmSkin.position_id')
                        ->groupBy('customerRelateHmSkin.position_id')
                        ->map(function($hm_skin_suggest, $position_id){
                            return [
                                'position_id' => $position_id,
                                'position_name' => trans('admin.hm_position_'.$position_id),
                                'suggest_by_position' => $hm_skin_suggest->sortBy('customerRelateHmSkin.detection_type_id')
                                    ->groupBy('customerRelateHmSkin.detection_type_id')
                                    ->map(function($hm_skin_suggest, $detection_type_id){
                                        return [
                                            'item_id'   => $detection_type_id,
                                            'item_name' => trans('admin.hm_itemsid_'.$detection_type_id),
                                            'suggest_by_item' => $hm_skin_suggest->sortBy('customerRelateHmSkin.level_sort')->values()
                                        ];
                                    })
                                    ->values()
                            ];
                        })->values()
                ];
            })->values();

        return $hm_skin_suggests;
    }

    /**
     * @param Request $request
     * @param $customer_id
     * @return array
     */
    private function assembleHmSkinSuggest(Request $request, $customer_id)
    {
        $data = $request->hm_skin_suggests;
        $language_ids = array_keys($data);

        $index = 0;
        $suggest_data = [];

        foreach($data[$language_ids[0]] as $position_id => $item_by_position)
        {
            foreach ($item_by_position as $item_id => $level) {
                foreach ($level as $level_sort => $item_suggest)
                {
                    $suggest_data[$index]['customer_relate_hm_skin'] = [
                        'customer_id'       => $customer_id,
                        'store_id'          => CustomerRelateHmSkin::STORE_ID_DEFAULT,
                        'position_id'       => $position_id,
                        'detection_type_id' => $item_id,
                        'level_sort'        => $level_sort,
                    ];
                    foreach ($language_ids as $language_id) {
                        $suggest_data[$index]['hm_skin_suggest'][] = [
                            'language_id' => $language_id,
                            'title'       => $data[$language_id][$position_id][$item_id][$level_sort]['title'],
                            'analysis'    => $data[$language_id][$position_id][$item_id][$level_sort]['analysis'],
                            'suggest'     => $data[$language_id][$position_id][$item_id][$level_sort]['suggest'],
                        ];
                    }
                    $index++;
                }
            }
        }

        return $suggest_data;
    }

    /**
     * @param $hm_skin_suggest
     * @param $customer_relate_hm_skin_id
     * @return mixed
     */
    public function assembleHmSkinSuggestByCustomerRelate($hm_skin_suggest, $customer_relate_hm_skin_id)
    {
        foreach($hm_skin_suggest as &$suggest_item)
        {
            $suggest_item['customer_relate_hm_skin_id'] = $customer_relate_hm_skin_id;
        }

        return $hm_skin_suggest;
    }

    /**
     * @throws \Exception
     */
    private function isSuperAdmin()
    {
        // 超管才能操作的
        $this->checkIsTrue(CustomerAdmin::isGuardSuperAdmin(), trans('admin.is_super_man'));
    }
}

